2020-2021 Sunseeker Telemetry and Lighting System
usci_b_i2c.c
Go to the documentation of this file.
1 //*****************************************************************************
2 //
3 // usci_b_i2c.c - Driver for the usci_b_i2c Module.
4 //
5 //*****************************************************************************
6 
7 //*****************************************************************************
8 //
11 //
12 //*****************************************************************************
13 
14 #include "inc/hw_memmap.h"
15 
16 #ifdef __MSP430_HAS_USCI_Bx__
17 #include "usci_b_i2c.h"
18 
19 #include <assert.h>
20 
21 void USCI_B_I2C_initMaster(uint16_t baseAddress, USCI_B_I2C_initMasterParam *param)
22 {
23  uint16_t preScalarValue;
24 
25  //Disable the USCI module and clears the other bits of control register
26  HWREG8(baseAddress + OFS_UCBxCTL1) = UCSWRST;
27 
28  /*
29  * Configure as I2C master mode.
30  * UCMST = Master mode
31  * UCMODE_3 = I2C mode
32  * UCSYNC = Synchronous mode
33  */
34  HWREG8(baseAddress + OFS_UCBxCTL0) = UCMST + UCMODE_3 + UCSYNC;
35 
36  //Configure I2C clock source
37  HWREG8(baseAddress + OFS_UCBxCTL1) = (param->selectClockSource + UCSWRST );
38 
39  /*
40  * Compute the clock divider that achieves the fastest speed less than or
41  * equal to the desired speed. The numerator is biased to favor a larger
42  * clock divider so that the resulting clock is always less than or equal
43  * to the desired clock, never greater.
44  */
45  preScalarValue = (unsigned short)(param->i2cClk / param->dataRate);
46  HWREG16(baseAddress + OFS_UCBxBRW) = preScalarValue;
47 }
48 void USCI_B_I2C_initSlave (uint16_t baseAddress,
49  uint8_t slaveAddress
50  )
51 {
52  //Disable the USCI module
53  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCSWRST;
54 
55  //Clear USCI master mode
56  HWREG8(baseAddress + OFS_UCBxCTL0) &= ~UCMST;
57 
58  //Confiugre I2C as Slave and Synchronous mode
59  HWREG8(baseAddress + OFS_UCBxCTL0) = UCMODE_3 + UCSYNC;
60 
61  //Set up the slave address.
62  HWREG16(baseAddress + OFS_UCBxI2COA) = slaveAddress;
63 }
64 
65 void USCI_B_I2C_enable (uint16_t baseAddress)
66 {
67  //Reset the UCSWRST bit to enable the USCI Module
68  HWREG8(baseAddress + OFS_UCBxCTL1) &= ~(UCSWRST);
69 }
70 
71 void USCI_B_I2C_disable (uint16_t baseAddress)
72 {
73  //Set the UCSWRST bit to disable the USCI Module
74  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCSWRST;
75 }
76 
77 void USCI_B_I2C_setSlaveAddress (uint16_t baseAddress,
78  uint8_t slaveAddress
79  )
80 {
81  //Set the address of the slave with which the master will communicate.
82  HWREG16(baseAddress + OFS_UCBxI2CSA) = (slaveAddress);
83 }
84 
85 void USCI_B_I2C_setMode (uint16_t baseAddress,
86  uint8_t mode
87  )
88 {
89  HWREG8(baseAddress + OFS_UCBxCTL1) &= ~USCI_B_I2C_TRANSMIT_MODE;
90  HWREG8(baseAddress + OFS_UCBxCTL1) |= mode;
91 }
92 
93 void USCI_B_I2C_slavePutData (uint16_t baseAddress,
94  uint8_t transmitData
95  )
96 {
97  //Send single byte data.
98  HWREG8(baseAddress + OFS_UCBxTXBUF) = transmitData;
99 }
100 
101 uint8_t USCI_B_I2C_slaveGetData (uint16_t baseAddress)
102 {
103  //Read a byte.
104  return (HWREG8(baseAddress + OFS_UCBxRXBUF));
105 }
106 
107 uint8_t USCI_B_I2C_isBusBusy (uint16_t baseAddress)
108 {
109  //Return the bus busy status.
110  return (HWREG8(baseAddress + OFS_UCBxSTAT) & UCBBUSY);
111 }
112 
113 uint8_t USCI_B_I2C_isBusy (uint16_t baseAddress)
114 {
115  //Return the busy status.
116  if ((HWREG8(baseAddress + OFS_UCBxIFG) & (UCTXIFG + UCRXIFG))){
117  return (USCI_B_I2C_BUS_BUSY);
118  } else {
119  return (USCI_B_I2C_BUS_NOT_BUSY);
120  }
121 }
122 
123 uint8_t USCI_B_I2C_masterIsStopSent (uint16_t baseAddress)
124 {
125  //Return the bus busy status.
126  return (HWREG8(baseAddress + OFS_UCBxCTL1) & UCTXSTP);
127 }
128 
129 uint8_t USCI_B_I2C_masterIsStartSent (uint16_t baseAddress)
130 {
131  //Return if master has sent start
132  return (HWREG8(baseAddress + OFS_UCBxCTL1) & UCTXSTT);
133 }
134 
135 void USCI_B_I2C_masterSendStart (uint16_t baseAddress)
136 {
137  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTT;
138 }
139 
140 void USCI_B_I2C_enableInterrupt (uint16_t baseAddress,
141  uint8_t mask
142  )
143 {
144  //Enable the interrupt masked bit
145  HWREG8(baseAddress + OFS_UCBxIE) |= mask;
146 }
147 
148 void USCI_B_I2C_disableInterrupt (uint16_t baseAddress,
149  uint8_t mask
150  )
151 {
152  //Disable the interrupt masked bit
153  HWREG8(baseAddress + OFS_UCBxIE) &= ~(mask);
154 }
155 
156 void USCI_B_I2C_clearInterrupt (uint16_t baseAddress,
157  uint8_t mask
158  )
159 {
160  //Clear the I2C interrupt source.
161  HWREG8(baseAddress + OFS_UCBxIFG) &= ~(mask);
162 }
163 
164 uint8_t USCI_B_I2C_getInterruptStatus (uint16_t baseAddress,
165  uint8_t mask
166  )
167 {
168  //Return the interrupt status of the request masked bit.
169  return (HWREG8(baseAddress + OFS_UCBxIFG) & mask);
170 }
171 
172 void USCI_B_I2C_masterSendSingleByte (uint16_t baseAddress,
173  uint8_t txData
174  )
175 {
176  //Store current TXIE status
177  uint8_t txieStatus = HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE;
178 
179  //Disable transmit interrupt enable
180  HWREG8(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
181 
182  //Send start condition.
183  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTR + UCTXSTT;
184 
185  //Poll for transmit interrupt flag.
186  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
187 
188  //Send single byte data.
189  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
190 
191  //Poll for transmit interrupt flag.
192  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
193 
194  //Send stop condition.
195  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
196 
197  //Clear transmit interrupt flag before enabling interrupt again
198  HWREG8(baseAddress + OFS_UCBxIFG) &= ~(UCTXIFG);
199 
200  //Reinstate transmit interrupt enable
201  HWREG8(baseAddress + OFS_UCBxIE) |= txieStatus;
202 }
203 
204 bool USCI_B_I2C_masterSendSingleByteWithTimeout (uint16_t baseAddress,
205  uint8_t txData,
206  uint32_t timeout
207  )
208 {
209  // Creating variable for second timeout scenario
210  uint32_t timeout2 = timeout;
211 
212  //Store current TXIE status
213  uint8_t txieStatus = HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE;
214 
215  //Disable transmit interrupt enable
216  HWREG8(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
217 
218  //Send start condition.
219  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTR + UCTXSTT;
220 
221  //Poll for transmit interrupt flag.
222  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout) ;
223 
224  //Check if transfer timed out
225  if (timeout == 0){
226  return (STATUS_FAIL);
227  }
228 
229  //Send single byte data.
230  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
231 
232  //Poll for transmit interrupt flag.
233  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout2) ;
234 
235  //Check if transfer timed out
236  if (timeout2 == 0){
237  return (STATUS_FAIL);
238  }
239 
240  //Send stop condition.
241  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
242 
243  //Clear transmit interrupt flag before enabling interrupt again
244  HWREG8(baseAddress + OFS_UCBxIFG) &= ~(UCTXIFG);
245 
246  //Reinstate transmit interrupt enable
247  HWREG8(baseAddress + OFS_UCBxIE) |= txieStatus;
248 
249  return (STATUS_SUCCESS);
250 }
251 
252 void USCI_B_I2C_masterSendMultiByteStart (uint16_t baseAddress,
253  uint8_t txData
254  )
255 {
256  //Store current transmit interrupt enable
257  uint8_t txieStatus = HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE;
258 
259  //Disable transmit interrupt enable
260  HWREG8(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
261 
262  //Send start condition.
263  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTR + UCTXSTT;
264 
265  //Poll for transmit interrupt flag.
266  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
267 
268  //Send single byte data.
269  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
270 
271  //Reinstate transmit interrupt enable
272  HWREG8(baseAddress + OFS_UCBxIE) |= txieStatus;
273 }
274 
275 bool USCI_B_I2C_masterSendMultiByteStartWithTimeout (uint16_t baseAddress,
276  uint8_t txData,
277  uint32_t timeout
278  )
279 {
280  //Store current transmit interrupt enable
281  uint8_t txieStatus = HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE;
282 
283  //Disable transmit interrupt enable
284  HWREG8(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
285 
286  //Send start condition.
287  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTR + UCTXSTT;
288 
289  //Poll for transmit interrupt flag.
290  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout) ;
291 
292  //Check if transfer timed out
293  if (timeout == 0){
294  return (STATUS_FAIL);
295  }
296 
297  //Send single byte data.
298  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
299 
300  //Reinstate transmit interrupt enable
301  HWREG8(baseAddress + OFS_UCBxIE) |= txieStatus;
302 
303  return(STATUS_SUCCESS);
304 }
305 
306 void USCI_B_I2C_masterSendMultiByteNext (uint16_t baseAddress,
307  uint8_t txData
308  )
309 {
310  //If interrupts are not used, poll for flags
311  if (!(HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE)){
312  //Poll for transmit interrupt flag.
313  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
314  }
315 
316  //Send single byte data.
317  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
318 }
319 
320 bool USCI_B_I2C_masterSendMultiByteNextWithTimeout (uint16_t baseAddress,
321  uint8_t txData,
322  uint32_t timeout
323  )
324 {
325  //If interrupts are not used, poll for flags
326  if (!(HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE)){
327  //Poll for transmit interrupt flag.
328  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout);
329 
330  //Check if transfer timed out
331  if (timeout == 0){
332  return (STATUS_FAIL);
333  }
334  }
335 
336  //Send single byte data.
337  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
338 
339  return(STATUS_SUCCESS);
340 }
341 
342 void USCI_B_I2C_masterSendMultiByteFinish (uint16_t baseAddress,
343  uint8_t txData
344  )
345 {
346  //If interrupts are not used, poll for flags
347  if (!(HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE)){
348  //Poll for transmit interrupt flag.
349  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
350  }
351 
352  //Send single byte data.
353  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
354 
355  //Poll for transmit interrupt flag.
356  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
357 
358  //Send stop condition.
359  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
360 }
361 
362 bool USCI_B_I2C_masterSendMultiByteFinishWithTimeout (uint16_t baseAddress,
363  uint8_t txData,
364  uint32_t timeout
365  )
366 {
367  uint32_t timeout2 = timeout;
368 
369  //If interrupts are not used, poll for flags
370  if (!(HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE)){
371  //Poll for transmit interrupt flag.
372  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout) ;
373 
374  //Check if transfer timed out
375  if (timeout == 0){
376  return (STATUS_FAIL);
377  }
378  }
379 
380  //Send single byte data.
381  HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;
382 
383  //Poll for transmit interrupt flag.
384  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout2) ;
385 
386  //Check if transfer timed out
387  if (timeout2 == 0){
388  return (STATUS_FAIL);
389  }
390 
391  //Send stop condition.
392  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
393 
394  return(STATUS_SUCCESS);
395 }
396 
397 void USCI_B_I2C_masterSendMultiByteStop (uint16_t baseAddress)
398 {
399  //If interrupts are not used, poll for flags
400  if (!(HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE)){
401  //Poll for transmit interrupt flag.
402  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
403  }
404 
405  //Send stop condition.
406  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
407 }
408 
409 bool USCI_B_I2C_masterSendMultiByteStopWithTimeout (uint16_t baseAddress,
410  uint32_t timeout)
411 {
412  //If interrupts are not used, poll for flags
413  if (!(HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE)){
414  //Poll for transmit interrupt flag.
415  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout) ;
416 
417  //Check if transfer timed out
418  if (timeout == 0){
419  return (STATUS_FAIL);
420  }
421  }
422 
423  //Send stop condition.
424  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
425 
426  return (STATUS_SUCCESS);
427 }
428 
429 void USCI_B_I2C_masterReceiveMultiByteStart (uint16_t baseAddress)
430 {
431  //Set USCI in Receive mode
432  HWREG8(baseAddress + OFS_UCBxCTL1) &= ~UCTR;
433  //Send start
434  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTT;
435 }
436 
437 uint8_t USCI_B_I2C_masterReceiveMultiByteNext (uint16_t baseAddress)
438 {
439  return (HWREG8(baseAddress + OFS_UCBxRXBUF));
440 }
441 
442 uint8_t USCI_B_I2C_masterReceiveMultiByteFinish (uint16_t baseAddress)
443 {
444  uint8_t receiveData;
445 
446  //Send stop condition.
447  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
448 
449  //Capture data from receive buffer after setting stop bit due to
450  //MSP430 I2C critical timing.
451  receiveData = HWREG8(baseAddress + OFS_UCBxRXBUF);
452 
453  //Wait for Stop to finish
454  while (HWREG8(baseAddress + OFS_UCBxCTL1) & UCTXSTP);
455 
456  //Wait for RX buffer
457  while (!(HWREG8(baseAddress + OFS_UCBxIFG) & UCRXIFG));
458 
459  return receiveData;
460 }
461 
462 bool USCI_B_I2C_masterReceiveMultiByteFinishWithTimeout (uint16_t baseAddress,
463  uint8_t *rxData,
464  uint32_t timeout
465  )
466 {
467  uint32_t timeout2 = timeout;
468 
469  //Send stop condition.
470  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
471 
472  //Capture data from receive buffer after setting stop bit due to
473  //MSP430 I2C critical timing.
474  *rxData = (HWREG8(baseAddress + OFS_UCBxRXBUF));
475 
476  //Wait for Stop to finish
477  while ((HWREG8(baseAddress + OFS_UCBxCTL1) & UCTXSTP) && --timeout);
478 
479  //Check if transfer timed out
480  if (timeout == 0){
481  return (STATUS_FAIL);
482  }
483 
484  // Wait for RX buffer
485  while ((!(HWREG8(baseAddress + OFS_UCBxIFG) & UCRXIFG)) && --timeout2) ;
486 
487  //Check if transfer timed out
488  if (timeout2 == 0){
489  return (STATUS_FAIL);
490  }
491 
492  return (STATUS_SUCCESS);
493 }
494 
495 void USCI_B_I2C_masterReceiveMultiByteStop (uint16_t baseAddress)
496 {
497  //Send stop condition.
498  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
499 }
500 
501 void USCI_B_I2C_masterReceiveSingleStart (uint16_t baseAddress)
502 {
503  //local variable to store GIE status
504  uint16_t gieStatus;
505 
506  //Store current SR register
507  gieStatus = __get_SR_register() & GIE;
508 
509  //Disable global interrupt
510  __disable_interrupt();
511 
512  //Set USCI in Receive mode
513  HWREG8(baseAddress + OFS_UCBxCTL1) &= ~UCTR;
514 
515  //Send start condition.
516  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTT;
517 
518  //Poll for Start bit to complete
519  while (HWREG8(baseAddress + OFS_UCBxCTL1) & UCTXSTT) ;
520 
521  //Send stop condition.
522  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
523 
524  //Reinstate SR register
525  __bis_SR_register(gieStatus);
526 }
527 
528 bool USCI_B_I2C_masterReceiveSingleStartWithTimeout (uint16_t baseAddress,
529  uint32_t timeout
530  )
531 {
532  //local variable to store GIE status
533  uint16_t gieStatus;
534 
535  //Store current SR register
536  gieStatus = __get_SR_register() & GIE;
537 
538  //Disable global interrupt
539  __disable_interrupt();
540 
541  //Set USCI in Receive mode
542  HWREG8(baseAddress + OFS_UCBxCTL1) &= ~UCTR;
543 
544  //Send start condition.
545  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTT;
546 
547  //Poll for Start bit to complete
548  while (((HWREG8(baseAddress + OFS_UCBxCTL1) & UCTXSTT)) && --timeout);
549 
550  //Check if transfer timed out
551  if (timeout == 0){
552  return (STATUS_FAIL);
553  }
554 
555  //Send stop condition.
556  HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
557 
558  //Reinstate SR register
559  __bis_SR_register(gieStatus);
560 
561  return (STATUS_SUCCESS);
562 }
563 
564 uint8_t USCI_B_I2C_masterReceiveSingle (uint16_t baseAddress)
565 {
566  //Polling RXIFG0 if RXIE is not enabled
567  if(!(HWREG8(baseAddress + OFS_UCBxIE) & UCRXIE)) {
568  while(!(HWREG8(baseAddress + OFS_UCBxIFG) & UCRXIFG));
569  }
570 
571  //Read a byte.
572  return (HWREG8(baseAddress + OFS_UCBxRXBUF));
573 }
574 
575 uint32_t USCI_B_I2C_getReceiveBufferAddressForDMA (uint16_t baseAddress)
576 {
577  return ( baseAddress + OFS_UCBxRXBUF );
578 }
579 
580 uint32_t USCI_B_I2C_getTransmitBufferAddressForDMA (uint16_t baseAddress)
581 {
582  return ( baseAddress + OFS_UCBxTXBUF );
583 }
584 
585 
586 #endif
587 //*****************************************************************************
588 //
591 //
592 //*****************************************************************************
uint8_t receiveData
uint8_t transmitData
MPU_initThreeSegmentsParam param
#define HWREG8(x)
Definition: hw_memmap.h:41
#define HWREG16(x)
Definition: hw_memmap.h:39
#define STATUS_FAIL
Definition: hw_memmap.h:23
#define STATUS_SUCCESS
Definition: hw_memmap.h:22